#include "config.h"

USART_InitTypeDef USART_InitStructure;

// LED ---------------------------------指示电源接通
void LED_GPIO_CONFIG(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
}

void LED_ON()
{
    GPIOA->BSRR = 0x4;
}

void LED_OFF()
{
    GPIOA->BRR = 0x4;
}

// USART-------------------------------------
// PB10--USART3_TX
// PB11--USART3_RX
void USART_RCC_CONFIG(void)
{
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, ENABLE);
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);
}

void USART_GPIO_CONFIG(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;

    // GPIO_PinRemapConfig(GPIO_FullRemap_USART3, ENABLE);

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOB, &GPIO_InitStructure);

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIO_Init(GPIOB, &GPIO_InitStructure);
}

void USART_NVIC_CONFIG(void)
{
    NVIC_InitTypeDef NVIC_InitStructure;
    NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
    NVIC_Init(&NVIC_InitStructure);
}

void USART_CONFIG(void)
{
    USART_InitStructure.USART_BaudRate = 9600;
    USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
    USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;
    USART_InitStructure.USART_Parity = USART_Parity_No;
    USART_InitStructure.USART_StopBits = USART_StopBits_1;
    USART_InitStructure.USART_WordLength = USART_WordLength_8b;
    USART_Init(USART3, &USART_InitStructure);
}

// TIM1_CH1 PWM( PA8 TIM1_CH1) -------------------------通过MOSFET 连接到低压电机
void PWM1_GPIO_CONFIG(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
}

void PWM1_TIM1_CONFIG(void)
{
    // 使能TIM1时钟
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);

    TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;

    // PWM频率 = 定时器时钟频率 / (TIM_Period + 1) / (TIM_Prescaler + 1)
    //  例如：64MHz / 1000 / 64 = 1kHz
    TIM_TimeBaseStructure.TIM_Prescaler = 63;
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
    TIM_TimeBaseStructure.TIM_Period = 1000 - 1; // PWM周期为1000
    TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
    TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);

    TIM_OCInitTypeDef TIM_OCInitStructure;
    TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
    TIM_OCInitStructure.TIM_Pulse = 500; // 初始占空比50%
    TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
    TIM_OC1Init(TIM1, &TIM_OCInitStructure);

    // 使能TIM1的ARR预装载寄存器
    TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable);

    // 使能TIM1的预装载寄存器
    TIM_ARRPreloadConfig(TIM1, ENABLE);

    TIM_CtrlPWMOutputs(TIM1, ENABLE);
}

// ADC1_IN0(PA0) 使用TIM2的第二个捕获比较寄存器按周期读取ADC1------------------------------- 连接低压放大器，检测低压压力传感器值
void ADC1_CONFIG(void)
{
    ADC_InitTypeDef ADC_InitStructrue;

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
    RCC_ADCCLKConfig(RCC_PCLK2_Div8); // 设置ADC时钟为PCLK2的8分频（64MHz / 8 = 8MHz）

    ADC_InitStructrue.ADC_Mode = ADC_Mode_Independent;                    // 独立模式
    ADC_InitStructrue.ADC_ScanConvMode = DISABLE;                         // 单通道模式
    ADC_InitStructrue.ADC_ContinuousConvMode = DISABLE;                   // 单次转换
    ADC_InitStructrue.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T2_CC2; // ADC_ExternalTrigConv_None;// ADC_ExternalTrigConv_T2_CC2; // TIM2_CC2触发
    ADC_InitStructrue.ADC_DataAlign = ADC_DataAlign_Right;                // 数据右对齐
    ADC_InitStructrue.ADC_NbrOfChannel = 1;                               // 1个转换通道
    ADC_Init(ADC1, &ADC_InitStructrue);

    // 配置ADC1通道0（PA0）
    ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_239Cycles5); // 选择ADC通道0（PA0），设置采样时间为239.5个周期

    // 使能ADC1的EOC（转换完成）中断
    ADC_ITConfig(ADC1, ADC_IT_EOC, ENABLE);

    ADC_ExternalTrigConvCmd(ADC1, ENABLE); // 确保外部触发使能

    ADC_Cmd(ADC1, ENABLE);

    // 校准ADC1
    ADC_ResetCalibration(ADC1);
    while (ADC_GetResetCalibrationStatus(ADC1))
        ;
    ADC_StartCalibration(ADC1);
    while (ADC_GetCalibrationStatus(ADC1))
        ;
}

void TIM2_Configuration(uint16_t period_ms)
{
    TIM_TimeBaseInitTypeDef TIM_BaseStructure;
    TIM_OCInitTypeDef TIM_OCInitStructure;

    // 计算TIM2的自动重装载值（ARR）和预分频器（PSC）
    // uint32_t tim2_clock = 64000000;           // TIM2时钟为64MHz
    uint32_t prescaler = 6400 - 1;            // 预分频器，64MHz / 6400 = 10kHz
    uint32_t period_ticks = (period_ms * 10); // 10kHz下，1ms = 10 ticks

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);

    // TIM2基本配置
    TIM_BaseStructure.TIM_Period = period_ticks - 1;
    TIM_BaseStructure.TIM_Prescaler = prescaler;
    TIM_BaseStructure.TIM_ClockDivision = 0;
    TIM_BaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
    TIM_TimeBaseInit(TIM2, &TIM_BaseStructure);

    // TIM_OCMode_Timing：仅生成内部比较匹配事件（无物理信号）
    // TIM_OCMode_Toggle：生成内部事件 + 引脚电平翻转

    // TIM2通道2配置为比较模式
    // TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Timing;
    // TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Disable;// 无需物理引脚输出
    TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Toggle; // 或TIM_OCMode_PWM1都行
    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
    TIM_OCInitStructure.TIM_Pulse = period_ticks / 2;
    TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
    TIM_OC2Init(TIM2, &TIM_OCInitStructure);

    // TIM_OCMode_Timing​ 模式下，只有通过初始化配置触发源（如 TIM_TRGOSource_OCxRef），才能让定时器在比较匹配时自动输出触发信号（TRGO）到 ADC,(​触发信号输出默认关闭)
    // TIM_OCMode_Toggle 模式下，自动通过引脚输出信号（触发信号同时传递到ADC）
    //  配置TIM2的触发输出为CC2事件
    //  TIM_SelectOutputTrigger(TIM2, TIM_TRGOSource_OC2Ref);

    TIM_Cmd(TIM2, ENABLE);
    // 启用TIM2的CC2中断
    TIM_ITConfig(TIM2, TIM_IT_CC2, ENABLE);
}

void NVIC_Configuration(void)
{
    NVIC_InitTypeDef NVIC_InitStructure;

    // 配置TIM2的CC2中断
    NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;           // TIM2中断通道
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; // 抢占优先级
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;        // 子优先级
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;           // 使能中断
    NVIC_Init(&NVIC_InitStructure);

    // 配置ADC1的EOC中断
    NVIC_InitStructure.NVIC_IRQChannel = ADC1_2_IRQn;         // ADC1中断通道
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; // 抢占优先级
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;        // 子优先级
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;           // 使能中断
    NVIC_Init(&NVIC_InitStructure);
}

uint16_t ADC1_Read(void)
{
    return ADC_GetConversionValue(ADC1);
}
